
package com.surprise.base.util;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.SqlTimestampConverter;
import org.apache.struts2.util.ListEntry;

/**
 * BeanUtilBean.java
 * @author xuling
 * 2017年1月20日
 */
public class BeanUtilBean extends BeanUtilsBean {

    protected BeanUtilBean(){
        super(BeanUtilsBean.getInstance().getConvertUtils(), BeanUtilsBean.getInstance().getPropertyUtils());

        getConvertUtils().register(new FloatConverter(null),  Float.class);
        getConvertUtils().register(new IntegerConverter(null),  Integer.class);
        getConvertUtils().register(new BigDecimalConverter(null),  BigDecimal.class);
        getConvertUtils().register(new DateConverter(null),  Date.class);
        getConvertUtils().register(new SqlTimestampConverter(null),  Timestamp.class);
    }

    @Override
    public void copyProperty(Object destItem, String name, Object orgItem)
            throws IllegalAccessException, InvocationTargetException{

        Field field = null;

        try {
            field = destItem.getClass().getDeclaredField(name);
        } catch (NoSuchFieldException e) {
            super.copyProperty(destItem, name, orgItem);
            return;
        }

        if (orgItem instanceof List && field.getType() == List.class){

            ParameterizedType paramType = (ParameterizedType)field.getGenericType();

            Class<?> paramCls = (Class<?>)paramType.getActualTypeArguments()[0];

            List<?> orgList = (List<?>) orgItem;
            List values = new ArrayList(orgList.size()); //
            try {
                for (Object tmp:orgList) {
                    if (paramCls == java.lang.String.class) {
                        if (tmp == null){
                            values.add(null);
                        } else {
                            values.add((String) tmp);
                        }
                    } else if (paramCls == ListEntry.class) {
                        if (tmp == null){
                            values.add(null);
                        } else {
                            values.add((ListEntry) tmp);
                        }
                    } else {
                        if (tmp == null){
                            values.add(null);
                        } else {
                            Object work = paramCls.newInstance();
                            BeanUtils.copyProperties(work, tmp);
                            values.add(work);
                        }
                    }
                }
            } catch (InstantiationException e) {
            }

            field.setAccessible(true);
            field.set(destItem, values);

        } else if (orgItem instanceof File && field.getType() == File.class) {
            super.copyProperty(destItem, name, orgItem);
        } else {
            super.copyProperty(destItem, name, orgItem);
        }
    }
}
